/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "icache.h"
#include "spi.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "gt_app.h"
#include "EPD_App.h"
#include "cJSON.h"
#include "gt_app.h"
#include "apl_zigbee_proto.h"
#include "apl_pwr_control.h"
#include "apl_key_scan.h"
#include "fml_debug.h"
#include "fml_zigbee.h"
#include "fml_key.h"
#include "fml_ota.h"

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */


/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
extern int CJSON_CDECL cJSON_main(void);
extern int8_t generator_qr(uint8_t* str, uint16_t x, uint16_t y);


//const char *test_json = "{\"code\":0,\"msg\":\"success\",\"data\":{\"taskId\":54,\"type\":3,\"content\":[{\"content\":\"-------------------------\",\"x\":0,\"y\":75,\"size\":16,\"weight\":32,\"type\":14},{\"content\":\"\u9759\u601d\u533a\",\"x\":174,\"y\":5,\"size\":25,\"weight\":35,\"type\":3},{\"content\":\"6\",\"x\":160,\"y\":35,\"size\":40,\"weight\":35,\"type\":4},{\"content\":\"0\",\"x\":192,\"y\":35,\"size\":40,\"weight\":35,\"type\":4},{\"content\":\"1\",\"x\":224,\"y\":35,\"size\":40,\"weight\":35,\"type\":4},{\"content\":\"2\",\"x\":256,\"y\":35,\"size\":40,\"weight\":35,\"type\":4},{\"content\":\"-------------------------\",\"x\":0,\"y\":171,\"size\":16,\"weight\":32,\"type\":14},{\"content\":\"http:\/\/ske.localhost\/reserve\/s\/HOO8i5\",\"x\":20,\"y\":20,\"size\":32,\"weight\":21,\"type\":12},{\"content\":\"\u7a7a \u95f2\",\"x\":110,\"y\":101,\"size\":60,\"weight\":50,\"type\":9},{\"content\":\"\u53cb\u60c5\",\"x\":148,\"y\":185,\"size\":16,\"weight\":16},{\"content\":\"1\",\"x\":180,\"y\":185,\"size\":16,\"weight\":16},{\"content\":\"2\",\"x\":192,\"y\":185,\"size\":16,\"weight\":16},{\"content\":\"3\",\"x\":204,\"y\":185,\"size\":16,\"weight\":16},{\"content\":\"\u63d0\u793a\",\"x\":216,\"y\":185,\"size\":16,\"weight\":16},{\"content\":\"\u6587\u660e\u9605\u89c8\u3001\u8bf7\u52ff\u996e\u98df\uff1b\u79bb\u9986\u8bf7\u5e26\u8d70\u4e2a\u4eba\u7269\u54c1\u4e00\",\"x\":0,\"y\":240,\"size\":16,\"weight\":16}],\"deviceMac\":\"70B3D5058002B748\"},\"sign\":\"ukv+7y8UDBzgxK\/C6XAT8Q==\",\"timeStamp\":1713434260}";


extern void parse_objects(const char* str);

static void Error_Handler(void)
{
    /* USER CODE BEGIN Error_Handler_Debug */
    /* User can add his own implementation to report the HAL error return state */
    __disable_irq();
    while (1)
    {
    }
    /* USER CODE END Error_Handler_Debug */
}

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
    /* USER CODE BEGIN 1 */

    /* USER CODE END 1 */

    /* MCU Configuration--------------------------------------------------------*/

    /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    HAL_Init();

    /* USER CODE BEGIN Init */

    /* USER CODE END Init */

    /* Configure the system clock */
    SystemClock_Config();

    /* USER CODE BEGIN SysInit */

    /* USER CODE END SysInit */

    /* Initialize all configured peripherals */
    MX_GPIO_Init();
    MX_SPI1_Init();
    MX_SPI2_Init();
    MX_ICACHE_Init();
    fml_debug_init();
    fml_zigbee_init();
    hal_pwm_gpio_init();
    hal_pwm_gpio_start();
    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 0);
    HAL_Delay(2000);
    fml_pwr_control_init();
    fml_key_init();

    if(DEV_Module_Init()!=0)
        return -1;

    //printf("e-Paper Init and Clear...\r\n");
    EPD_3IN52_Init();
    init_lcd();
    
    printf("Version: 0.0.09\n");
    printf("BOOT_START_ADDR: %08x\n", BOOT_START_ADDR);
    printf("BOOT_SIZE: %dK\n", BOOT_SIZE/1024);
    printf("CONFIG_START_ADDR: %08x\n", CONFIG_START_ADDR);
    printf("CONFIG_SIZE: %dK\n", CONFIG_SIZE/1024);
    printf("APP_START_ADDR: %08x\n", APP_START_ADDR);
    printf("APP_SIZE: %dK\n", APP_SIZE/1024);
    printf("APP_BAK_START_ADDR: %08x\n", APP_BAK_START_ADDR);
    printf("APP_BAK_SIZE: %dK\n", APP_BAK_SIZE/1024); 
    printf("JSON_DATA_START_ADDR: %08x\n", JSON_DATA_START_ADDR);
    printf("JSON_DATA_SIZE: %dK\n", JSON_DATA_SIZE/1024);

    //lcd_test();

    int gt = gt_init();
    //if(gt <= 0)
    //  Paint_DrawString_EN(10, 20, "gt init fail", &Font12, WHITE, BLACK);
    //else
    //  Paint_DrawString_EN(10, 20, "gt init pass", &Font12, WHITE, BLACK);
    Paint_DrawString_EN(10, 100, "waiting for connection", &Font12, BLACK, WHITE);
    EPD_3IN52_display(BIT_MAP);
    EPD_3IN52_refresh();

    //generator_qr("http:\/\/test.skalibrary.com.cn\/reserve\/s\/vjPCu1", 10, 100);
    //EPD_3IN52_display(BIT_MAP);
    //EPD_3IN52_refresh();

    if (fml_ota_init() == 0)
    {
        printf("APP Version = %s\r\n", g_ota_info.app_version);

        uint8_t *json_data = malloc(JSON_DATA_SIZE);
        if (json_data)
        {
            memset(json_data, 0, JSON_DATA_SIZE);
            hal_flash_read(json_data, CONFIG_START_ADDR, FLASH_PAGE_SIZE);

            //parse_objects(json_data);

            free(json_data);
        }
    }

    app_init();
    /* USER CODE END 2 */
    
    //parse_objects(test_json);

    //Paint_DrawString_EN(10, 260, "260testtestestestest", &Font12, BLACK, WHITE);
    //EPD_3IN52_display(BIT_MAP);
    //EPD_3IN52_refresh();
    
    //Paint_DrawString_EN(10, 280, "299299299299229", &Font12, BLACK, WHITE);
    //EPD_3IN52_display(BIT_MAP);
    //EPD_3IN52_refresh();
    
    //Paint_DrawString_EN(380, 280, "X", &Font12, BLACK, WHITE);
    //EPD_3IN52_display(BIT_MAP);
    //EPD_3IN52_refresh();
    
    while (1)
    {
        apl_business_task();
        apl_proto_parse_task();
        //apl_pwr_control_task();
        apl_key_scan_task();

        if(HAL_GetTick()%100==0)
        {
            HAL_GPIO_TogglePin(LED_B_GPIO_Port, LED_B_Pin);
            HAL_GPIO_TogglePin(LED_G_GPIO_Port, LED_G_Pin);
        }
        
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
    }
    /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE0) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 4;
  RCC_OscInitStruct.PLL.PLLN = 55;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */


#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
